#include <stdio.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_tim.h>
#include <stm32f10x_exti.h>
#include <stm32f10x.h>
#include <CoOS.h>
#include <Config.h>
#include <Keypad4x4.h>

#define Set_Row1	GPIO_WriteBit(Keypad4x4_Row_GPIO1, Keypad4x4_Row1, Bit_SET)
#define Set_Row2	GPIO_WriteBit(Keypad4x4_Row_GPIO2, Keypad4x4_Row2, Bit_SET)
#define Set_Row3	GPIO_WriteBit(Keypad4x4_Row_GPIO2, Keypad4x4_Row3, Bit_SET)
#define Set_Row4	GPIO_WriteBit(Keypad4x4_Row_GPIO1, Keypad4x4_Row4, Bit_SET)
#define Reset_Row1	GPIO_WriteBit(Keypad4x4_Row_GPIO1, Keypad4x4_Row1, Bit_RESET)
#define Reset_Row2	GPIO_WriteBit(Keypad4x4_Row_GPIO2, Keypad4x4_Row2, Bit_RESET)
#define Reset_Row3	GPIO_WriteBit(Keypad4x4_Row_GPIO2, Keypad4x4_Row3, Bit_RESET)
#define Reset_Row4	GPIO_WriteBit(Keypad4x4_Row_GPIO1, Keypad4x4_Row4, Bit_RESET)

static unsigned int Key_Sel = 0;

void Keypad4x4Config(void) {
	GPIO_InitTypeDef GPIO_InitStructure;
	//
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB
			| RCC_APB2Periph_GPIOC, ENABLE);
	//CONFIG Keypad row pins
	GPIO_InitStructure.GPIO_Pin = Keypad4x4_Row1 | Keypad4x4_Row4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(Keypad4x4_Row_GPIO1, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin = Keypad4x4_Row2 | Keypad4x4_Row3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(Keypad4x4_Row_GPIO2, &GPIO_InitStructure);
	//CONFIG Keypad col pins
	GPIO_InitStructure.GPIO_Pin = Keypad4x4_Col1 | Keypad4x4_Col2
			|Keypad4x4_Col3 | Keypad4x4_Col4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(Keypad4x4_Col_GPIO, &GPIO_InitStructure);
}

void ShiftRow(unsigned int row) {
	if (row == 1) {
		Set_Row1;
		Reset_Row2;
		Reset_Row3;
		Reset_Row4;
	} else if (row == 2) {
		Reset_Row1;
		Set_Row2;
		Reset_Row3;
		Reset_Row4;
	} else if (row == 3) {
		Reset_Row1;
		Reset_Row2;
		Set_Row3;
		Reset_Row4;
	} else if (row == 4) {
		Reset_Row1;
		Reset_Row2;
		Reset_Row3;
		Set_Row4;
	}
}

unsigned int ScanRow(void) {
	if (GPIO_ReadOutputDataBit(Keypad4x4_Row_GPIO1, Keypad4x4_Row1) == Bit_SET) {
		return 1;
	}
	if (GPIO_ReadOutputDataBit(Keypad4x4_Row_GPIO2, Keypad4x4_Row2) == Bit_SET) {
		return 2;
	}
	if (GPIO_ReadOutputDataBit(Keypad4x4_Row_GPIO2, Keypad4x4_Row3) == Bit_SET) {
		return 3;
	}
	if (GPIO_ReadOutputDataBit(Keypad4x4_Row_GPIO1, Keypad4x4_Row4) == Bit_SET) {
		return 4;
	}
	return 0;
}

unsigned int ScanCol(void) {
	if (GPIO_ReadInputDataBit(Keypad4x4_Col_GPIO, Keypad4x4_Col1) == Bit_SET) {
		return 1;
	}
	if (GPIO_ReadInputDataBit(Keypad4x4_Col_GPIO, Keypad4x4_Col2) == Bit_SET) {
		return 2;
	}
	if (GPIO_ReadInputDataBit(Keypad4x4_Col_GPIO, Keypad4x4_Col3) == Bit_SET) {
		return 3;
	}
	if (GPIO_ReadInputDataBit(Keypad4x4_Col_GPIO, Keypad4x4_Col4) == Bit_SET) {
		return 4;
	}
	return 0;
}

unsigned int ReadKeypad4x4(void) {
	return Key_Sel;
}

/*
 * ************************************************************
 * below is IRQhandler functions
 * ************************************************************
 */
void TIM6_IRQHandler(void) {
	unsigned int tmp;
	if (TIM_GetITStatus(TIM6, TIM_IT_Update) == SET) {
		tmp = ScanRow();
		//Key_Sel = ScanCol() + tmp * 10;
		Key_Sel = ScanCol();
		if (Key_Sel != 0) {
			Key_Sel = Key_Sel + tmp*10;
		}
		if (tmp == 4) {
			tmp = 1;
		} else {
			tmp++;
		}
		ShiftRow(tmp);
		TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
	}
}

